package com.qiaofang.collectmanage.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.qiaofang.collectmanage.dao.HouseAgentEsDao;
import com.qiaofang.collectmanage.dao.domain.HouseAgent;
import com.qiaofang.collectmanage.dao.elasticsearch.EsClient;
import com.qiaofang.collectmanage.dao.util.ConfigUtils;
import com.qiaofang.collectmanage.service.HouseAgentService;
import com.qiaofang.collectmanage.service.common.utils.DateUtils;
import com.qiaofang.collectmanage.service.util.BeanUtil;
import com.qiaofang.collectmanage.service.util.HouseAgentServiceConvert;
import com.qiaofang.collectmanage.stub.bean.*;
import com.qiaofang.collectmanage.stub.constants.*;
import com.qiaofang.common.exception.BusinessException;
import com.qiaofang.common.model.page.PageDTO;
import com.qiaofang.common.util.ConverterBeanUtil;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author yi.li
 * @date 2018/08/20
 */
@Service
public class HouseAgentServiceImpl implements HouseAgentService {

    private static final Logger logger = LoggerFactory.getLogger(HouseAgentServiceImpl.class);

    @Autowired
    private HouseAgentEsDao houseAgentEsDao;

    @Override
    public HouseAgentDTO getHouseAgent(GetHouseAgentDTO dto) {
        HouseAgent domain = houseAgentEsDao.getHouseAgent(HouseAgentServiceConvert.convertGetDTO2Domain(dto));
        return HouseAgentServiceConvert.convertDomain2DTO(domain);
    }

    @Override
    public void saveHouseAgent(SaveHouseAgentDTO saveHouseAgentDTO) {
        saveHouseAgentDTO.setAgentUuid(UUID.randomUUID().toString());
        saveHouseAgentDTO.setDeleted(DeletedEnum.NO.getValue());
        saveHouseAgentDTO.setCreatedTime(DateUtils.formatDate(new Date()));
        HouseAgent getHouseAgent = new HouseAgent();
        getHouseAgent.setAgentTelephone(saveHouseAgentDTO.getAgentTelephone());
        //判断是否存在手机号
        HouseAgent houseAgentReturn = houseAgentEsDao.getHouseAgent(getHouseAgent);
        if (houseAgentReturn != null) {
            if (DeletedEnum.NO.getValue().equals(houseAgentReturn.getDeleted())) {
                throw new BusinessException(HouseAgentResponseCode.HOUSE_AGENT_EXIST.getResponseCode(), HouseAgentResponseCode.HOUSE_AGENT_EXIST.getResponseMessage());
            } else {
                //更新索引
                if (houseAgentReturn.getAgentUuid() != null && !"".equals(houseAgentReturn.getAgentUuid())) {
                    saveHouseAgentDTO.setAgentUuid(houseAgentReturn.getAgentUuid());
                    saveHouseAgentDTO.setDeleted(DeletedEnum.NO.getValue());
                }
            }
        }
        //更新房源判断是否为中介
        List<BatchUpdateHouseAgentDTO> batchUpdateHouseAgentDTOs = new ArrayList<>();
        BatchUpdateHouseAgentDTO batchUpdateHouseAgentDTO = new BatchUpdateHouseAgentDTO();
        batchUpdateHouseAgentDTO.setAgentTelephone(saveHouseAgentDTO.getAgentTelephone());
        batchUpdateHouseAgentDTOs.add(batchUpdateHouseAgentDTO);
        batchUpdateRentalAndSaleHouseAgent(batchUpdateHouseAgentDTOs, 1);
        //添加中介数据
        EsClient.addIndexAdd(ConfigUtils.getIndexHswhHouseAgent(), TableConstants.INDEX_TYPE_AGENT, saveHouseAgentDTO);
    }

    @Override
    public long removeHouseAgent(RemoveHouseAgentDTO removeHouseAgentDTO) {
        GetHouseAgentDTO getHouseAgentDTO = new GetHouseAgentDTO();
        getHouseAgentDTO.setAgentUuid(removeHouseAgentDTO.getAgentUuid());
        removeHouseAgentDTO.setUpdatedTime(DateUtils.formatDate(new Date()));
        HouseAgentDTO houseAgentDTO = getHouseAgent(getHouseAgentDTO);
        if (houseAgentDTO != null && houseAgentDTO.getAgentUuid() != null && !"".equals(houseAgentDTO.getAgentUuid())) {
            List<BatchUpdateHouseAgentDTO> batchUpdateHouseAgentDTOs = new ArrayList<>();
            BatchUpdateHouseAgentDTO batchUpdateHouseAgentDTO = new BatchUpdateHouseAgentDTO();
            batchUpdateHouseAgentDTO.setUpdatedTime(DateUtils.formatDate(new Date()));
            batchUpdateHouseAgentDTO.setUpdatedUserName(removeHouseAgentDTO.getUpdatedUserName());
            batchUpdateHouseAgentDTO.setAgentTelephone(houseAgentDTO.getAgentTelephone());
            batchUpdateHouseAgentDTOs.add(batchUpdateHouseAgentDTO);
            //删除中介数据时,更新房源的房源中介标识
            batchUpdateRentalAndSaleHouseAgent(batchUpdateHouseAgentDTOs, 0);
            houseAgentEsDao.deleteIndex(ConfigUtils.getIndexHswhHouseAgent(), TableConstants.INDEX_TYPE_AGENT, removeHouseAgentDTO);
        } else {
            throw new BusinessException(HouseAgentResponseCode.HOUSE_AGENT_NOTEXIST.getResponseCode(), HouseAgentResponseCode.HOUSE_AGENT_NOTEXIST.getResponseMessage());
        }
        return 0;
    }

    @Override
    public int updateHouseAgent(UpdateHouseAgentDTO updateHouseAgentDTO) {
        EsClient.updateIndex(ConfigUtils.getIndexHswhHouseAgent(), TableConstants.INDEX_TYPE_AGENT, updateHouseAgentDTO);
        return 0;
    }

    @Override
    public void batchUpdateHouseAgent(List<BatchUpdateHouseAgentDTO> batchUpdateHouseAgentDTOs) {
        //更新房源数据判断是否为中介
        houseAgentEsDao.batchUpdateHouseAgent(ConfigUtils.getIndexHswhRentalHouse(), TableConstants.INDEX_TYPE_RENTAL_HOUSE, batchUpdateHouseAgentDTOs, 1);
        houseAgentEsDao.batchUpdateHouseAgent(ConfigUtils.getIndexHswhSaleHouse(), TableConstants.INDEX_TYPE_SALE_HOUSE, batchUpdateHouseAgentDTOs, 1);
    }

    @Override
    public List<BatchGetHouseAgentRepeatDTO> batchGetHouseAgentRepeat(List<BatchUpdateHouseAgentDTO> batchUpdateHouseAgentDTOs) {
        return houseAgentEsDao.batchGetHouseAgentRepeat(ConfigUtils.getIndexHswhHouseAgent(), TableConstants.INDEX_TYPE_AGENT, batchUpdateHouseAgentDTOs);
    }

    @Override
    public List<BatchGetHouseAgentRepeatDTO> batchGetHouseAgentRepeatDeletedOrNotDeleted(List<BatchUpdateHouseAgentDTO> batchUpdateHouseAgentDTOs) {
        return houseAgentEsDao.batchGetHouseAgentRepeatDeletedOrNotDeleted(ConfigUtils.getIndexHswhHouseAgent(), TableConstants.INDEX_TYPE_AGENT, batchUpdateHouseAgentDTOs);
    }

    /**
     * 新增的中介号码
     * @param batchUpdateHouseAgentDTO
     * @return
     */
    public JSONObject fromObject(BatchUpdateHouseAgentDTO batchUpdateHouseAgentDTO) {
        String uuid = UUID.randomUUID().toString();
        batchUpdateHouseAgentDTO.setDeleted(DeletedEnum.NO.getValue());
        batchUpdateHouseAgentDTO.setAgentUuid(uuid);
        String time = DateUtils.formatDate(new Date());
        batchUpdateHouseAgentDTO.setUpdatedTime(time);
        batchUpdateHouseAgentDTO.setCreatedTime(time);
        JSONObject obj = JSONObject.parseObject(JSONObject.toJSON(batchUpdateHouseAgentDTO).toString());
        return obj;
    }

    /**
     * 已有的中介号码,只要批量更新
     * @param batchGetHouseAgentRepeatDTO
     * @param List<BatchUpdateHouseAgentDTO>
     * @return
     */
    public JSONObject fromBatchGetHouseAgentRepeatDTO(BatchGetHouseAgentRepeatDTO batchGetHouseAgentRepeatDTO, List<BatchUpdateHouseAgentDTO> batchUpdateHouseAgentDTOs) {
            BatchUpdateHouseAgentDTO batchUpdateHouseAgentDTO = batchUpdateHouseAgentDTOs.get(0);
            batchGetHouseAgentRepeatDTO.setDeleted(DeletedEnum.NO.getValue());
            batchGetHouseAgentRepeatDTO.setUpdatedUserName(batchUpdateHouseAgentDTO.getUpdatedUserName());
            batchGetHouseAgentRepeatDTO.setUpdatedTime(DateUtils.formatDate(new Date()));
            for(BatchUpdateHouseAgentDTO src :batchUpdateHouseAgentDTOs){
                if(batchGetHouseAgentRepeatDTO.getAgentTelephone().equals(src.getAgentTelephone())){
                    batchGetHouseAgentRepeatDTO.setAgentUserName(src.getAgentUserName());
                }
            }
            JSONObject obj = JSONObject.parseObject(JSONObject.toJSON(batchGetHouseAgentRepeatDTO).toString());
            return obj;
    }

    @Override
    public void batchSaveHouseAgent(List<BatchUpdateHouseAgentDTO> batchUpdateHouseAgentDTOs) {
        if (batchUpdateHouseAgentDTOs != null && !batchUpdateHouseAgentDTOs.isEmpty()) {
            //获取重复的中介号
            List<BatchGetHouseAgentRepeatDTO> batchGetHouseAgentRepeats = batchGetHouseAgentRepeatDeletedOrNotDeleted(batchUpdateHouseAgentDTOs);
            List<BatchUpdateHouseAgentDTO> batchUpdateHouseAgentDTORepeat = new ArrayList<>();
            ConverterBeanUtil.copyListBeanPropertiesToList(batchGetHouseAgentRepeats, batchUpdateHouseAgentDTORepeat, BatchUpdateHouseAgentDTO.class);
            List<JSONObject> repeatHouseAgentDTOS = batchGetHouseAgentRepeats.stream().map(batchGetHouseAgentRepeatDTO -> fromBatchGetHouseAgentRepeatDTO(batchGetHouseAgentRepeatDTO, batchUpdateHouseAgentDTOs)).collect(Collectors.toList());
            //提取出不包含重复手机号的集合
            List<BatchUpdateHouseAgentDTO> newBatchUpdateHouseAgentDTOs = batchUpdateHouseAgentDTOs.stream().filter(item -> !batchUpdateHouseAgentDTORepeat.contains(item)).collect(Collectors.toList());
            List<JSONObject> newHouseAgentOBJs = newBatchUpdateHouseAgentDTOs.stream().map(batchUpdateHouseAgentDTO -> fromObject(batchUpdateHouseAgentDTO)).collect(Collectors.toList());
            newHouseAgentOBJs.addAll(repeatHouseAgentDTOS);
            //批量添加中介数据
            try {
                if (!newHouseAgentOBJs.isEmpty()) {
                    EsClient.addDoBulk(ConfigUtils.getIndexHswhHouseAgent(), TableConstants.INDEX_TYPE_AGENT, "agentUuid", newHouseAgentOBJs);
                    logger.info("添加中介号码{}", newHouseAgentOBJs);
                }
            } catch (Exception e) {
                logger.error("导入时批量添加中介信息失败{}", e);
                throw new BusinessException("导入时批量添加中介信息失败");
            }
        }
    }

    private void batchUpdateRentalAndSaleHouseAgent(List<BatchUpdateHouseAgentDTO> batchUpdateHouseAgentDTOs, int isAgent) {
        houseAgentEsDao.batchUpdateHouseAgent(ConfigUtils.getIndexHswhRentalHouse(), TableConstants.INDEX_TYPE_RENTAL_HOUSE, batchUpdateHouseAgentDTOs, isAgent);
        houseAgentEsDao.batchUpdateHouseAgent(ConfigUtils.getIndexHswhSaleHouse(), TableConstants.INDEX_TYPE_SALE_HOUSE, batchUpdateHouseAgentDTOs, isAgent);
    }


    @Override
    public Long countSearchHouseAgentPage(SearchHouseAgentPostDTO searchHouseAgentPostDTO, PageDTO pageDTO) {
        try {
            QueryBuilder queryBuilder = QueryBuilders.boolQuery();
            if (searchHouseAgentPostDTO.getAgentTelephone() != null && !"".equals(searchHouseAgentPostDTO.getAgentTelephone())) {
                ((BoolQueryBuilder) queryBuilder).must(QueryBuilders.termQuery("agentTelephone", searchHouseAgentPostDTO.getAgentTelephone()));
            }
            if (searchHouseAgentPostDTO.getAgentUserName() != null && !"".equals(searchHouseAgentPostDTO.getAgentUserName())) {
                ((BoolQueryBuilder) queryBuilder).must(QueryBuilders.termQuery("agentUserName", searchHouseAgentPostDTO.getAgentUserName()));
            }
            ((BoolQueryBuilder) queryBuilder).must(QueryBuilders.termQuery("deleted", DeletedEnum.NO.getValue()));
            SearchResponse searchResponse = EsClient.queryHouseAgentData(ConfigUtils.getIndexHswhHouseAgent(), TableConstants.INDEX_TYPE_AGENT, queryBuilder, pageDTO.getOffset(), pageDTO.getPageSize());
            logger.info("查询eslticsearch success");
            if (searchResponse != null) {
                SearchHits hits = searchResponse.getHits();
                if (hits != null && hits.getHits().length != 0) {
                    return hits.getTotalHits();
                }
            }
        } catch (Exception e) {
            logger.error("countSearchHouseAgentPage=>{}", e);
        }
        return 0L;
    }

    @Override
    public List<HouseAgentDTO> searchHouseAgentPage(SearchHouseAgentPostDTO searchHouseAgentPostDTO, PageDTO pageDTO) {
        List<HouseAgentDTO> houseAgentDTOs = new ArrayList<>();
        try {
            QueryBuilder queryBuilder = QueryBuilders.boolQuery();
            if (searchHouseAgentPostDTO.getAgentTelephone() != null && !"".equals(searchHouseAgentPostDTO.getAgentTelephone())) {
                ((BoolQueryBuilder) queryBuilder).must(QueryBuilders.termQuery("agentTelephone", searchHouseAgentPostDTO.getAgentTelephone()));
            }
            if (searchHouseAgentPostDTO.getAgentUserName() != null && !"".equals(searchHouseAgentPostDTO.getAgentUserName())) {
                ((BoolQueryBuilder) queryBuilder).must(QueryBuilders.termQuery("agentUserName", searchHouseAgentPostDTO.getAgentUserName()));
            }
            ((BoolQueryBuilder) queryBuilder).must(QueryBuilders.termQuery("deleted", DeletedEnum.NO.getValue()));
            SearchResponse searchResponse = EsClient.queryHouseAgentData(ConfigUtils.getIndexHswhHouseAgent(), TableConstants.INDEX_TYPE_AGENT, queryBuilder, pageDTO.getOffset(), pageDTO.getPageSize());
            logger.info("查询eslticsearch success");
            if (searchResponse != null) {
                SearchHits hits = searchResponse.getHits();
                SearchHit[] hits1 = hits.getHits();
                for (SearchHit hit : hits1) {
                    Map<String, Object> source = hit.getSource();
                    HouseAgentDTO hswhHouseAgent = BeanUtil.mapperObj(source, HouseAgentDTO.class);
                    hswhHouseAgent.setAgentUuid(hit.getId());
                    houseAgentDTOs.add(hswhHouseAgent);
                }
            }
        } catch (Exception e) {
            logger.error("searchHouseAgentPage=>{}", e);
        }
        return houseAgentDTOs;
    }
}
